#!/usr/bin/env bash
######################################################
# Arturo
# Programming Language + Bytecode VM compiler
# (c) 2019-2021 Yanis Zafirópulos
#
# @file: install
######################################################

source tools/utils.sh

################################################
# FUNCTIONS
################################################

verifyDirectories() {
    # create target dirs recursively, if not exists
    mkdir -p "$TARGET_DIR"
    mkdir -p "$TARGET_LIB"

    info "in: $ROOT_DIR"

    if [[ ":$PATH:" == *":$TARGET_DIR:"* ]]; 
        :
    then
        # path was not in path
        PATH=$TARGET_DIR:$PATH      
    fi
}

buildArturo(){
    info "version: $(cat version/version) b/$(cat version/build)"
    info "config: $CONFIG"

    eecho "${GRAY}"
    if [ ! $PRINT_LOG ] && [ ! $IS_DEV_BUILD ];
    then
        nim $COMPILER $FLAGS -o:$BINARY $MAIN 2>/dev/null &
        animate_progress
    else
        nim $COMPILER $FLAGS -o:$BINARY $MAIN
    fi
    eecho "${CLEAR}"
}

compressBinary(){
    info "compressing binary"
    if $FOR_WEB; then
        if command_exists uglifyjs ;
        then
            uglifyjs $BINARY -c -m "toplevel,reserved=['A$']" -c -o ${BINARY/.js/.min.js}
        fi
    else
        if ! command_exists upx ; 
        then
            upx -q $BINARY >/dev/null 2>&1
        fi
    fi
}

installAll(){
    cp $BINARY $TARGET_DIR

    if $RUN_UNIT_TESTS; then
        ./tools/tester.art
    fi
}

################################################
# INITIALIZE OPTIONS
################################################

# paths and tools

ROOT_DIR="$HOME/.arturo"
TARGET_DIR="$ROOT_DIR/bin"
TARGET_LIB="$ROOT_DIR/lib"

BINARY="bin/arturo"
MAIN="src/arturo.nim"
COMPILER="c"

# variables

MINI_BUILD=false
COMPRESS=true
PRINT_LOG=false
RUN_UNIT_TESTS=false
FOR_WEB=false


if [ "$(whoami)" = "drkameleon" ]; then IS_DEV_BUILD=true
else IS_DEV_BUILD=false
fi

CONFIG=""
#--warning[UnusedImport]:off\

# check switches

while test $# -gt 0
do
    case "$1" in
        log)
            PRINT_LOG=true;;
        dev)
            IS_DEV_BUILD=true;;
        test)
            RUN_UNIT_TESTS=true;;
        release)
            FLAGS="$FLAGS --passC:'-flto'";;
        mini)      
            MINI_BUILD=true 
            FLAGS="$FLAGS -d:NOASCIIDECODE \
                          -d:NOEXAMPLES \
                          -d:NOGMP \
                          -d:NOPARSERS \
                          -d:NOSQLITE \
                          -d:NOUNZIP \
                          -d:NOWEBVIEW \
                          -d:MINI";;

        safe)
            FLAGS="$FLAGS -d:SAFE";;
        web)
            # TODO(install) make Web builds mini, by default
            #  labels: enhancement,cleanup,installer,web
            FOR_WEB=true
            COMPILER="js"
            BINARY="$BINARY.js"
            FLAGS="$FLAGS -d:NOASCIIDECODE \
                          -d:NOEXAMPLES \
                          -d:NOGMP \
                          -d:NOPARSERS \
                          -d:NOSQLITE \
                          -d:NOUNZIP \
                          -d:NOWEBVIEW"
            FLAGS="$FLAGS --verbosity:3"
            FLAGS="$FLAGS -d:WEB ";;

        noasciidecode)  FLAGS="$FLAGS -d:NOASCIIDECODE";;
        noexamples)     FLAGS="$FLAGS -d:NOEXAMPLES";;
        nogmp)          FLAGS="$FLAGS -d:NOGMP";;
        noparsers)      FLAGS="$FLAGS -d:NOPARSERS";;
        nosqlite)       FLAGS="$FLAGS -d:NOSQLITE";;
        nounzip)        FLAGS="$FLAGS -d:NOUNZIP";;
        nowebview)      FLAGS="$FLAGS -d:NOWEBVIEW";;
        
        arm)
            FLAGS="$FLAGS --cpu:arm";;
        arm64)
            FLAGS="$FLAGS --cpu:arm64 --gcc.path:/usr/bin"
            FLAGS="$FLAGS --gcc.exe:aarch64-linux-gnu-gcc --gcc.linkerexe:aarch64-linux-gnu-gcc";;
        verbose) 	
            CONFIG="verbose $CONFIG"
            FLAGS="$FLAGS -d:VERBOSE";;
        benchmark) 	
            CONFIG="benchmark $CONFIG"
            FLAGS="$FLAGS -d:BENCHMARK";;
        debug) 		
            COMPRESS=false
            CONFIG="debug $CONFIG"
            FLAGS="$FLAGS -d:DEBUG --debugger:on --debuginfo --linedir:on";;
        profile) 	
            CONFIG="profile $CONFIG"
            FLAGS="$FLAGS -d:PROFILE --profiler:on --stackTrace:on";;
        *) ;;
    esac
    shift
done

if $MINI_BUILD; then 
    CONFIG="@mini $CONFIG"
    FLAGS="$FLAGS --opt:size"
else 
    CONFIG="@full $CONFIG"
    FLAGS="$FLAGS --opt:speed" 
fi

if $IS_DEV_BUILD; then
    awk '{sub(/[[:digit:]]+$/,$NF+1)}1' version/build > version/build_tmp && mv version/build_tmp version/build
    git commit -m 'build update' version/build

    FLAGS="$FLAGS -d:DEV --hints:on"
fi

################################################
# MAIN
################################################

showHeader "Installer"

section "Checking environment..."
verifyOS
verifyShell
verifyNim

section "Building..."
buildArturo

if [ $? -eq 0 ];
then
    section "Post-processing..."
    compressBinary

    section "Installing..."
    verifyDirectories
    installAll

    section "Done!"
    showFooter

    exit 0
else
    eecho "The installer failed :(" >&2
    exit 1
fi